package com.mall.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mall.constants.OrderStatusConstant;
import com.mall.constants.PaymentMethodConstant;
import com.mall.constants.StatusConstants;
import com.mall.context.BaseContext;
import com.mall.domain.dto.PaymentDTO;
import com.mall.domain.dto.PaymentPageQueryDTO;
import com.mall.domain.po.Order;
import com.mall.domain.po.Payment;
import com.mall.domain.po.User;
import com.mall.domain.vo.PaymentVO;
import com.mall.exception.BalanceNotEnoughException;
import com.mall.exception.OrderStatusException;
import com.mall.mapper.OrderMapper;
import com.mall.mapper.PaymentMapper;
import com.mall.mapper.UserMapper;
import com.mall.result.PageResult;
import com.mall.service.PaymentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * @description: 支付服务业务层实现类
 * @author 勾新杰
 * @version 1.0
 * @date 2024/11/25 14:47
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class PaymentServiceImpl implements PaymentService {

    private final OrderMapper orderMapper;

    private final UserMapper userMapper;

    private final PaymentMapper paymentMapper;

    /**
     * 支付
     *
     * @param paymentDTO 支付传输对象
     */
    @Override
    @Transactional
    public void pay(PaymentDTO paymentDTO) {
        Integer paymentMethod = paymentDTO.getPaymentMethod();
        if (Objects.equals(paymentMethod, PaymentMethodConstant.BALANCE)){
            // 1. 获取订单信息
            Long orderId = paymentDTO.getOrderId();
            Order order = orderMapper.getById(orderId);
            if (!Objects.equals(order.getOrderStatus(), OrderStatusConstant.UNPAID)){
                throw new OrderStatusException("订单状态异常");
            }
            // 2. 获取用户信息
            Long userId = BaseContext.getCurrentId();
            User user = userMapper.getUserById(userId);
            // 3. 判断余额是否充足
            Double totalAmount = order.getTotalAmount();
            if (user.getBalance() < totalAmount){
                throw new BalanceNotEnoughException("余额不足");
            }
            // 4. 更新用户余额
            userMapper.deductBalance(totalAmount, user.getId());
            // 5. 构建订单信息
            Order update = Order.builder()
                    .id(orderId)
                    .paymentTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
                    .orderStatus(OrderStatusConstant.UNSHIPPED)
                    .build();
            // 6. 更新订单信息
            orderMapper.update(update);
            // 7. 插入支付记录
            Payment payment = Payment.builder()
                    .orderId(orderId)
                    .userId(userId)
                    .paymentMethod(paymentMethod)
                    .amount(totalAmount)
                    .status(StatusConstants.ENABLE)
                    .createTime(LocalDateTime.now())
                    .build();
            paymentMapper.insert(payment);
        } else if (Objects.equals(paymentMethod, PaymentMethodConstant.ALIPAY)) {
            // TODO: 支付宝支付
            log.info("支付宝支付已完成");
        } else {
            // TODO: 微信支付
            log.info("微信支付已完成");
        }
    }

    /**
     * 查看支付记录
     *
     * @param paymentPageQueryDTO 支付分页查询传输对象
     * @return 支付分页视图对象
     */
    @Override
    public PageResult<PaymentVO> historyPayment(PaymentPageQueryDTO paymentPageQueryDTO) {
        // 1. 设置分页参数
        PageHelper.startPage(paymentPageQueryDTO.getPageNo(), paymentPageQueryDTO.getPageSize());
        // 2. 执行查询
        Page<PaymentVO> page = paymentMapper.page(paymentPageQueryDTO);
        // 3. 封装返回
        return new PageResult<>(page.getTotal(), page.getResult());
    }
}
